<?php

namespace app\company\controller\report;

use app\common\controller\CompanyController;
use app\common\model\Dealer;
use app\common\model\Driver;
use app\common\model\DealerGoods;
use app\common\model\DealerGoodsSpec;
use app\common\model\DeliveryLog;
use app\common\model\GoodsCate;
use app\common\service\annotation\ControllerAnnotation;
use app\common\service\annotation\NodeAnnotation;
use app\company\model\CompanyOrder;
use app\company\model\CompanyOrderDetail;
use app\company\model\Delivery;
use app\company\model\DealerOrder;
use app\company\model\ReportGoodsOut;
use app\company\model\ReportPurchaseOut;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard\Number;
use think\App;
use think\Paginator;
use think\response\Json;
use think\facade\Db;
use jianyan\excel\Excel;

/**
 * @ControllerAnnotation(title="物流报表")
 */
class Logistics extends CompanyController
{
    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->model = new ReportGoodsOut();
    }

    /**
     * @NodeAnnotation(title="司机物流报表")
     */

    public function driver()
    {
        $param = $this->request->get();
        $filter = [];
        if (isset($param['filter'])) {
            $filter = json_decode(stripslashes($param['filter']), true);
        }

        //搜索经销商
        $where = [];
        if (isset($filter['driver_name'])) {
            $driver_name = $filter['driver_name'];
            $driver = new Driver();
            $driver_id_data = $driver->where('name', 'like', '%' . $driver_name . '%')->column('id');
            array_push($where, ['driver_id', 'in', implode(',', $driver_id_data)]);
        }
        //按照时间搜索
        if (isset($filter['create_time'])) {
            $create_time = $filter['create_time'];
            $start_time = strtotime($create_time[0]);
            $end_time = strtotime('+1 day -1 second',  strtotime($create_time[1]));
            $where[] = ['create_time', 'between', [$start_time, $end_time]];
        }



        $skip = ceil(($param['page'] - 1) * $param['limit']);
        $delivery_log = new DeliveryLog();

        //需要是本公司下的经销商和司机
        $sql = $delivery_log->where($this->defaultWhere)->field('driver_id,count(driver_id) as driver_count ')->where($where)
            ->group('driver_id');
        if (isset($param['export'])  && $param['export']  == true) {
            $data = $sql->select()->toArray();
            $data =  $this->fordata_driver($data);
        } else {
            $data = $sql->paginate($param['limit'] ?? 15)->toArray();
            $data['data'] = $this->fordata_driver($data['data']);

            //合计
            $all_data = $sql->select()->toArray();
            $all_data =  $this->fordata_driver($all_data);
            $data['order_count'] = array_sum(array_column($all_data, 'order_count'));
            $data['store_count'] = array_sum(array_column($all_data, 'store_count'));
            $data['weight'] = array_sum(array_column($all_data, 'weight'));
            $data['volume'] = array_sum(array_column($all_data, 'volume'));
            $data['goods_value'] = array_sum(array_column($all_data, 'goods_value'));
            $data['distribution_expenditure'] = array_sum(array_column($all_data, 'distribution_expenditure'));
            $data['amount_receivable'] = array_sum(array_column($all_data, 'amount_receivable'));
            $data['paid_in_amount'] = array_sum(array_column($all_data, 'paid_in_amount'));
        }



        if (isset($param['export'])  && $param['export']  == true) {
            $header = [
                ['司机名称', 'driver_name'],
                ['配送次数', 'order_count'],
                ['门店数量', 'store_count'],
                ['商品重量', 'weight'],
                ['商品体积', 'volume'],
                ['配送货值', 'goods_value'],
                ['配送提成', 'distribution_expenditure'],
                ['应收金额', 'amount_receivable'],
                ['实收金额', 'paid_in_amount']
            ];


            $fileName = '司机物流统计报表';
            return Excel::exportData($data, $header, $fileName, 'xlsx');
        } else {
            $row_total = $sql->count();
            return $this->success($data);
        }
    }

    public function fordata_driver($data)
    {
        $company_order = new CompanyOrder();
        $company_order_detail = new CompanyOrderDetail();
        $delivery_log = new DeliveryLog();
        $driver_model = new Driver();
        $dealer_goods_spec = new DealerGoodsSpec();
        foreach ($data as $k => &$v) {
            // $v['order_count'] = $delivery_log->where('driver_id',$v['driver_id'])->count('company_order_id');

            //查找订单金额
            $order_count = 0;
            $order_amount = 0;

            //司机名称
            $v['driver_name'] = $driver_model->where('id', $v['driver_id'])->field('name')->value('name');

            //订单数量
            $v['order_count'] = $order_count;
            //门店数量
            $store_data = $delivery_log->where('driver_id', $v['driver_id'])->field('store_id,count(store_id) as store_count ')
                ->group('store_id')->select()->toArray();
            $v['store_count'] = $store_data[0]['store_count'];


            //订单合计
            $order_total = 0;
            $distribution_expenditure = 0;
            $goods_value = 0;

            $delivery_log_data = $delivery_log->alias('dl')
                ->field('dl.company_order_id,dl.order_amount,co.driver_money,co.delivery_amount')
                ->where('dl.driver_id', $v['driver_id'])
                ->leftJoin('company_order co', 'co.id = dl.company_order_id')->select()->toArray();
            $paid_in_amount = 0;
            $volume = 0;
            $weight = 0;
            //   halt($delivery_log_data);
            foreach ($delivery_log_data as $k2 => $v2) {
                $order_amount += $v2['order_amount']??0;
                $order_count += 1;
                $order_total += $v2['order_amount'] ?? 0;
                $distribution_expenditure += $v2['driver_money'] ?? 0;
                $paid_in_amount += $v2['delivery_amount'] ?? 0; //司机签收金额


                //订单详情
                $company_order_detail_data = $company_order_detail->field('id,dealer_goods_spec_id,sale_price,num')->where('company_order_id', $v2['company_order_id'])->find();


                if (!empty($company_order_detail_data)) {
                    foreach ($company_order_detail_data as $k4 => $v4) {
                        $goods_value += floatval($v4['sale_price']) * floatval($v4['num']);
                        //查找规格信息

                        $dealer_goods_spec_data = $dealer_goods_spec->field('width,height,length,weight')->where('id', $v4['dealer_goods_spec_id'])->find();
                        $spec_width = $dealer_goods_spec_data['width'];
                        $spec_height = $dealer_goods_spec_data['height'];
                        $spec_length = $dealer_goods_spec_data['length'];
                        $spec_weight = $dealer_goods_spec_data['weight'];
                        //体积
                        $volume  += $spec_width * $spec_height * $spec_length * $v4['num'];
                        //重量
                        $weight += $spec_weight * $v4['num'];
                    }
                }
            };
            //商品重量
            $v['weight'] = $weight;
            //商品体积
            $v['volume'] = $volume;

            //订单合计
            $v['order_total'] = sprintf("%.2f", $order_total);
            //货值合计
            $v['goods_value'] =  sprintf("%.2f", $goods_value);
            //应收金额
            $v['amount_receivable'] = sprintf("%.2f", $order_total);
            //实收金额
            $v['paid_in_amount'] = sprintf("%.2f", $paid_in_amount);
            //配送支出
            $v['distribution_expenditure'] = sprintf("%.2f", $distribution_expenditure);
        };
        return $data;
    }

    /**
     * @NodeAnnotation(title="经销商物流报表")
     */
    public function dealer()
    {
        $param = $this->request->get();
        $filter = [];
        if (isset($param['filter'])) {
            $filter = json_decode(stripslashes($param['filter']), true);
        }
        $skip = ceil(($param['page'] - 1) * $param['limit']);
        //搜索经销商
        $where = [];
        if (isset($filter['dealer_name'])) {
            $dealer_name = $filter['dealer_name'];
            $dealer = new Dealer();
            $dearler_id_data = $dealer->where('name', 'like', '%' . $dealer_name . '%')->column('id');
            array_push($where, ['dealer_id', 'in', implode(',', $dearler_id_data)]);
        }
        if (!empty($filter['dealer_id'])) {
            $where[] = ['dealer_id', '=', $filter['dealer_id']];
        }

        //按照时间搜索
        if (isset($filter['create_time'])) {
            $create_time = $filter['create_time'];
            $start_time = strtotime($create_time[0]);
            $end_time = strtotime('+1 day -1 second', strtotime($create_time[1]));
            $where[] = ['create_time', 'between', [$start_time, $end_time]];
        }

        $delivery_log = new DeliveryLog();
        $sql =  $delivery_log->where($this->defaultWhere)->field('dealer_id,count(dealer_id) as dealer_count ')->where($where)->group('dealer_id');
        if (isset($param['export'])  && $param['export']  == true) {
            $data = $sql->select()->toArray();
            $data = $this->fordata_dealer($data);
        } else {
            $data = $sql->paginate($param['limit'] ?? 15)->toArray();
            $data['data'] = $this->fordata_dealer($data['data']);

            //合计
            $all_data = $sql->select()->toArray();
            $all_data =  $this->fordata_dealer($all_data);
            $data['order_count'] = array_sum(array_column($all_data, 'order_count'));
            $data['store_count'] = array_sum(array_column($all_data, 'store_count'));
            $data['weight'] = array_sum(array_column($all_data, 'weight'));
            $data['volume'] = array_sum(array_column($all_data, 'volume'));
            $data['goods_value'] = array_sum(array_column($all_data, 'goods_value'));
            $data['distribution_expenditure'] = array_sum(array_column($all_data, 'distribution_expenditure'));
            $data['amount_receivable'] = array_sum(array_column($all_data, 'amount_receivable'));
            $data['paid_in_amount'] = array_sum(array_column($all_data, 'paid_in_amount'));
        }



        if (isset($param['export'])  && $param['export']  == true) {
            $header = [
                ['经销商', 'dealer_name'],
                ['配送订单', 'order_count'],
                ['门店数量', 'store_count'],
                ['商品重量', 'weight'],
                ['商品体积', 'volume'],
                ['配送货值', 'goods_value'],
                ['配送提成', 'distribution_expenditure'],
                ['应收金额', 'amount_receivable'],
                ['实收金额', 'paid_in_amount']
            ];


            $fileName = '经销商物流统计报表';
            return Excel::exportData($data, $header, $fileName, 'xlsx');
        } else {
            return $this->success($data);
        }
    }

    public function fordata_dealer($data)
    {
        $delivery_log = new DeliveryLog();
        $company_order = new CompanyOrder();
        $dealer = new Dealer();
        $company_order_detail = new CompanyOrderDetail();
        $dealer_goods_spec = new DealerGoodsSpec();
        foreach ($data as $k => &$v) {
            //获取经销商名称
            $v['dealer_name'] =  $dealer->where('id', $v['dealer_id'])->value('name');
            //获取订单数量
            $v['order_count'] = $delivery_log->where('dealer_id', $v['dealer_id'])->count('company_order_pid');
            //门店数量
            $store_data = $delivery_log->where('dealer_id', $v['dealer_id'])->field('store_id,count(store_id) as store_count ')
                ->group('store_id')->select()->toArray();
            $v['store_count'] = $store_data[0]['store_count'];

            //订单合计
            $order_total = 0;
            $distribution_expenditure = 0;
            $goods_value = 0;
            //经销商配送数据
            $delivery_log_data = $delivery_log->alias('dl')
            ->field('dl.company_order_id,dl.order_amount,co.driver_money,co.delivery_amount')
            ->where('dl.dealer_id', $v['dealer_id'])
            ->leftJoin('company_order co', 'co.id = dl.company_order_id')->select()->toArray();

          
            $paid_in_amount = 0;
            $volume = 0;
            $weight = 0;
            //   var_dump($delivery_log_data);
            foreach ($delivery_log_data as $k2 => $v2) {
               
                $order_total += $v2['order_amount'] ?? 0;
                $distribution_expenditure += $v2['driver_money'] ?? 0;
                $paid_in_amount += $v2['delivery_amount'] ?? 0; //司机签收金额

                //订单详情
                $company_order_detail_data = $company_order_detail->field('id,dealer_goods_spec_id,sale_price,num')->where('company_order_pid', $v2['company_order_id'])->find();


                if (!empty($company_order_detail_data)) {
                    foreach ($company_order_detail_data as $k4 => $v4) {
                        $goods_value += $v4['sale_price'] * $v4['num'];
                        //查找规格信息
                        $dealer_goods_spec_data = $dealer_goods_spec->field('width,height,length,weight')->where('id', $v4['dealer_goods_spec_id'])->find();
                        $spec_width = $dealer_goods_spec_data['width'];
                        $spec_height = $dealer_goods_spec_data['height'];
                        $spec_length = $dealer_goods_spec_data['length'];
                        $spec_weight = $dealer_goods_spec_data['weight'];
                        //体积
                        $volume += $spec_width * $spec_height * $spec_length * $v4['num'];
                        //重量
                        $weight += $spec_weight * $v4['num'];
                    }
                }
            };
            //商品重量
            $v['weight'] = $weight;
            //商品体积
            $v['volume'] = $volume;
            //订单合计
            $v['order_total'] = sprintf("%.2f", $order_total);
            //货值合计
            $v['goods_value'] =  sprintf("%.2f", $goods_value);
            //应收金额
            $v['amount_receivable'] = sprintf("%.2f", $order_total);
            //实收金额
            $v['paid_in_amount'] = sprintf("%.2f", $paid_in_amount);
            //配送支出
            $v['distribution_expenditure'] = sprintf("%.2f", $distribution_expenditure);
        }
        return $data;
    }


    /**
     * @NodeAnnotation(title="导出")
     */
    public function export_excel(): bool
    {
        // 获取表名
        $header = [];
        $header[] = ['ID', 'id'];
        $header[] = ['父级ID', 'pid'];
        $header[] = ['分类名称', 'name'];
        $cate_mode = new GoodsCate();
        $list     = $cate_mode->field('id,pid,name')->select()->toArray();
        $fileName = '分类参考模版';
        return Excel::exportData($list, $header, $fileName, 'xlsx');
    }

    public function dealStock($vo): void
    {
        $spec = json_decode($vo->spec()->select(), true);
        usort($spec, function ($a, $b) {
            return $b['ratio'] <=> $a['ratio'];  // 使用太空船操作符进行升序排序
        });
        $sales_str = $warehouse_str = '';
        $sales_stock = $old_sales_stock = $vo->sales_stock;
        $warehouse_stock = $old_warehouse_stock = $vo->warehouse_stock;
        $unit = '';
        foreach ($spec as $value) {
            if (!$value['ratio']) continue;
            // 售卖库存
            $sales_quotient = intdiv($sales_stock, $value['ratio']);
            $sales_stock = $sales_stock % $value['ratio'];
            $sales_str .= $sales_quotient . $value['unit'];
            // 库内库存
            $warehouse_quotient = intdiv($warehouse_stock, $value['ratio']);
            $warehouse_stock = $warehouse_stock % $value['ratio'];
            $warehouse_str .= $warehouse_quotient . $value['unit'];
            if ($value['unit_type'] == 1) $unit = $value['unit'];
        }
        $vo->sales_stock = $sales_str . ' = ' . $old_sales_stock . $unit;
        $vo->warehouse_stock = $warehouse_str . ' = ' . $old_warehouse_stock . $unit;
    }

    /**
     * @NodeAnnotation(title="update_delivery_log")
     */
    public function  update_delivery_log()
    {

        $delivery_log = new DeliveryLog();
        $delivery_log->chunk(100, function ($data) {
            $delivery_log = new DeliveryLog();
            $company_order = new CompanyOrder();
            foreach ($data as $k => $v) {
                $dealer_id = $company_order->where('id', $v['company_order_pid'])->value('dealer_id');
                $delivery_log->where('id', $v['id'])->update(['dealer_id' => $dealer_id]);
            }
        });
    }
}
